// 第一种会报错，当拷贝的数据或对象为undefined
// let copyArr = JSON.parse( JSON.stringify(arr) );

let arr = [1, { a: 2 }];
let obj = {
    a: 1,
    b: {
        c: 2,
        d: [1, 3]
    }
}

function deepCopy(arr) {
    if (typeof arr !== "object") { // 数组和对象的typeof都是object
        return arr
    }
    let copyArr = (arr.constructor === Array) ? [] : {}; // 判断是数组还是对象
    for (let i in arr) {
        if (typeof arr[i] === 'object') {   // 判断是值类型还是引用类型
            copyArr[i] = deepCopy(arr[i]);  // 引用类型的话进行递归操作
        } else {
            copyArr[i] = arr[i];  // 值类型直接赋值
        }
    }
    return copyArr;
}

let copyArr = deepCopy(arr);
console.log(copyArr)  // [1, {a: 2}]
arr[1].a = 3;
console.log(copyArr)  // [1, {a: 2}]
copyArr[1].a = 5;
console.log(arr)       // [1, {a: 2}]
console.log(copyArr)

let copyObj = deepCopy(obj)
obj.a = 3
console.log(copyObj, obj, "obj");

// 其他方法
// 方法一： 利用for循环+push
let arr = [1, 2, 3, 4, 5];
let resArr = [];
for (let i = 0; i <= arr.lenght - 1; i++) {
    resArr.push(arr[i])
}
console.log(resArr) //[1, 2, 3, 4, 5]

// 方法二： 利用slice截取特定范围内容不会影响原数据的方法
let arr = [1, 2, 3, 4, 5];
let resArr2 = arr.slice(0);
console.log(resArr2); //[1, 2, 3, 4, 5]

// 方法三： 利用concat合并空得到一个新数组
let arr = [1, 2, 3];
let resArr3 = arr.concat();
console.log(resArr3) //[1, 2, 3]

// 方法四：利用ES6数组的扩展运算符 ... 展开得到一个新数组
let arr = [1, 2, 3];
let arr1 = [...arr];
console.log(arr1) //[1, 2, 3]


// ==================================================
//  *需要注意的是，如果属性中有function则不能正确深复制
let obj = { name: '小明', age: 18 };
let newObj = JSON.parse(JOSN.stringify(obj))

// 
let obj1 = { name: '小明', age: 18 };
function cloneObj(originObj) {
    let originObjProto = Object.getPrototypeOf(originObj);
    return Object.assign(Object.create(originObjProto), originObj)
}
let newObj1 = cloneObj(obj1)
